<template>
  <div class="time-range-dialog" tabindex="1" v-if="visible" :style="popperStyle" :class="popperClass" @blur="$parent.hide()">
    <div class="time-range-picker-dialog">
      <div class="time-range-picker-dialog-start">
        <div class="title">开始时间</div>
        <div class="list">
          <div class="hours" ref="startHour" v-if="config.hasHours">
            <ul>
              <li @click.stop="clickTime('startHour',item)" :ref="'startHour' + item" v-for="(item,index) in startHours" :key="index" :class="{disabled:config.disabledHours.length && config.disabledHours.includes(item),selected:item == startHour}">
                <span>{{item}}</span>
              </li>
            </ul>
          </div>
          <div class="minutes" ref="startMinute" v-if="config.hasMinutes">
            <ul>
              <li @click.stop="clickTime('startMinute',item)" :ref="'startMinute' + item" v-for="(item,index) in startMinutes" :key="index" :class="{disabled:config.disabledMinutes.length && config.disabledMinutes.includes(item),selected:item == startMinute}">
                <span>{{item}}</span>
              </li>
            </ul>
          </div>
          <div class="seconds" ref="startSecond" v-if="config.hasSeconds">
            <ul>
              <li @click.stop="clickTime('startSecond',item)" :ref="'startSecond' + item" v-for="(item,index) in startSeconds" :key="index" :class="{disabled:config.disabledSeconds.length && config.disabledSeconds.includes(item),selected:item == startSecond}">
                <span>{{item}}</span>
              </li>
            </ul>
          </div>
          <div class="unit" ref="startUnit" v-if="config['use12-hours']">
            <ul>
              <li @click.stop="clickTime('startUnit',item)" :ref="'startUnit' + item" v-for="(item,index) in unit" :key="index" :class="{selected:item == startUnit}">
                <span>{{item}}</span>
              </li>
            </ul>
          </div>
        </div>
      </div>
      <div class="time-range-picker-dialog-end">
        <div class="title">结束时间</div>
        <div class="list">
          <div class="hours" ref="endHour" v-if="config.hasHours">
            <ul>
              <li @click.stop="clickTime('endHour',item)" :ref="'endHour' + item" v-for="(item,index) in endHours" :key="index" :class="{disabled:config.disabledHours.length && config.disabledHours.includes(item),selected:item == endHour}">
                <span>{{item}}</span>
              </li>
            </ul>
          </div>
          <div class="minutes" ref="endMinute" v-if="config.hasMinutes">
            <ul>
              <li @click.stop="clickTime('endMinute',item)" :ref="'endMinute' + item" v-for="(item,index) in endMinutes" :key="index" :class="{disabled:config.disabledMinutes.length && config.disabledMinutes.includes(item),selected:item == endMinute}">
                <span>{{item}}</span>
              </li>
            </ul>
          </div>
          <div class="seconds" ref="endSecond" v-if="config.hasSeconds">
            <ul>
              <li @click.stop="clickTime('endSecond',item)" :ref="'endSecond' + item" v-for="(item,index) in endSeconds" :key="index" :class="{disabled:config.disabledSeconds.length && config.disabledSeconds.includes(item),selected:item == endSecond}">
                <span>{{item}}</span>
              </li>
            </ul>
          </div>
          <div class="unit" ref="endUnit" v-if="config['use12-hours']">
            <ul>
              <li @click.stop="clickTime('endUnit',item)" :ref="'endUnit' + item" v-for="(item,index) in unit" :key="index" :class="{selected:item == endUnit}">
                <span>{{item}}</span>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>
    <div class="time-range-picker-dialog-footer">
      <template v-if="$slots.footer">
        <slot name="footer"></slot>
      </template>
      <div class="time-range-picker-dialog-footer-btn" v-else>
        <span @click.stop="confirmNow" class="now" :class="{hidden:!config.showNow}">此刻</span>
        <div class="method">
          <span @click.stop="reset" class="cancel">取消</span>
          <span @click.stop="confirm" class="confirm">确定</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Dialog',
  props: {
    startTime: {
      type: String,
      default: ''
    },
    endTime: {
      type: String,
      default: ''
    },
    config: {
      type: Object,
      default: () => {}
    },
    visible: {
      type: Boolean,
      default: false
    },
    popperClass:{
        type:String,
        default:null
    },
    popperStyle: {
      type: Object,
      default: () => {}
    }
  },
  computed: {
    startHours() {
      let num = 24
      if (this.config['use12-hours']) {
        num = 12
      }
      return this.setArray(num, this.config.hoursStep)
    },
    startMinutes() {
      return this.setArray(60, this.config.minutesStep)
    },
    startSeconds() {
      return this.setArray(60, this.config.secondsStep)
    },
    endHours() {
      let num = 24
      if (this.config['use12-hours']) {
        num = 12
      }
      return this.setArray(num, this.config.hoursStep)
    },
    endMinutes() {
      return this.setArray(60, this.config.minutesStep)
    },
    endSeconds() {
      return this.setArray(60, this.config.secondsStep)
    },
    unit() {
      return ['AM', 'PM']
    }
  },
  watch: {
    visible: {
      handler(data) {
        if (data === true) {
          let startTime = this.$moment(this.startTime, 'HH:mm:ss').format(
            'HH:mm:ss'
          )
          let endTime = this.$moment(this.endTime, 'HH:mm:ss').format(
            'HH:mm:ss'
          )
          if (this.config['use12-hours']) {
            startTime = this.$moment(this.startTime, 'HH:mm:ss a').format(
              'HH:mm:ss a'
            )
            endTime = this.$moment(this.endTime, 'HH:mm:ss a').format(
              'HH:mm:ss a'
            )
          }
          // 开始时间
          if (this.startTime.indexOf(':') != -1) {
            let data = startTime.split(':')
            this.clickTime('startHour', data[0])
            this.clickTime('startMinute', data[1])
            if (this.config['use12-hours']) {
              this.clickTime('startSecond', data[2].split(' ')[0])
              this.clickTime('startUnit', this.unitsName[data[2].split(' ')[1]])
            } else {
              this.clickTime('startSecond', data[2])
              this.startUnit = ''
            }
          }
          // 结束时间
          if (this.endTime.indexOf(':') != -1) {
            let data = endTime.split(':')
            this.clickTime('endHour', data[0])
            this.clickTime('endMinute', data[1])
            if (this.config['use12-hours']) {
              this.endSecond = data[2].split(' ')[0]
              this.clickTime('endSecond', data[2].split(' ')[0])
              this.clickTime('endUnit', this.unitsName[data[2].split(' ')[1]])
            } else {
              this.clickTime('endSecond', data[2])
              this.endUnit = ''
            }
          }
          const body = document.querySelector('body')
          if (body.append) {
            body.append(this.$el)
          } else {
            body.appendChild(this.$el)
          }
          this.$nextTick(() => {
            this.createPopper()
            this.handleClick()
          })
        } else {
          this.reset()
          this.remove()
        }
      }
    }
  },
  data() {
    return {
      startHour: '', // 开始小时
      startMinute: '', // 开始分钟
      startSecond: '', // 开始秒钟
      startUnit: '', // 开始单位
      endHour: '', // 结束小时
      endMinute: '', // 结束分钟
      endSecond: '', // 结束秒钟
      endUnit: '', // 结束单位
      unitsName: {
        上午: 'AM',
        凌晨: 'AM',
        中午: 'PM',
        下午: 'PM',
        晚上: 'PM'
      }
    }
  },

  methods: {
    // 生成数组
    setArray(length, step) {
      let data = Array.from({ length }).map((v, k) => {
        if (k < 10) {
          k = '0' + k
        }
        return k
      })
      return data.filter((item) => item % step == 0)
    },
    // 选中
    clickTime(name, item) {
      this[name] = item
      this.$nextTick(() => {
        if (item == 'AM') item = 0
        else if (item == 'PM') item = 1
        this.$refs[name].scrollTop = item * 32
      })
    },
    // 此刻
    confirmNow() {
      this.$emit('confirm', new Date(), new Date())
      this.$parent.hide()
    },
    // 聚焦
    handleClick() {
      // 聚焦不滚动，不定位
      this.$el.focus({ preventScroll: true })
    },
    // 移除组件
    remove() {
      this.$el.parentNode.removeChild(this.$el)
    },
    // 弹框定位
    createPopper() {
      const button = this.$parent.$el
      const tooltip = this.$el
      this.$utils.createPopper(button, tooltip, {
        placement: 'bottom-start',
        flipBehavior: 'flip'
      })
    },
    // 确定
    confirm() {
      let startTime =
        this.startHour + ':' + this.startMinute + ':' + this.startSecond
      let endTime = this.endHour + ':' + this.endMinute + ':' + this.endSecond
      if (this.config['use12-hours']) {
        startTime += ' ' + this.startUnit
        endTime += ' ' + this.endUnit
      }
      if (startTime.trim() === '::') {
        startTime = ''
      }
      if (endTime.trim() === '::') {
        endTime = ''
      }
      this.$emit('confirm', startTime, endTime)
      this.$parent.hide()
    },
    // 取消
    reset() {
      this.startHour = ''
      this.startMinute = ''
      this.startSecond = ''
      this.startUnit = ''
      this.endHour = ''
      this.endMinute = ''
      this.endSecond = ''
      this.endUnit = ''
      this.$emit('confirm', this.startTime, this.endTime)
      this.$parent.hide()
    }
  }
}
</script>

<style lang="less" scoped>
.time-range-dialog {
  background-color: #fff;
  z-index: 99;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 10%);
  &:focus,&:focus-visible{
      outline: none;
  }
  .time-range-picker-dialog {
    display: flex;
    &-start,
    &-end {
      flex: 1;
      text-align: center;
      padding: 5px 10px 10px;
      .title {
        padding: 10px 0;
        line-height: 1.5;
      }
      .list {
        display: flex;
        border: 1px solid #d9d9d9;
        ul,
        li {
          margin: 0;
          padding: 0;
        }
        li {
          list-style: none;
          height: 32px;
          line-height: 32px;
          color: #606266;
          cursor: pointer;
          .active:not(.disabled) {
            color: #303133;
            font-weight: 700;
          }
          &:not(.disabled):hover {
            background: #f5f7fa;
          }
        }
        .disabled {
          color: #c0c4cc;
          cursor: not-allowed;
        }
        .selected {
          background: #e6f7ff;
        }
        .hours,
        .minutes,
        .seconds,
        .unit {
          width: 45px;
          text-align: center;
          max-height: 192px;
          overflow-y: auto;
          overflow-x: hidden;
          &::after {
            display: block;
            content: '';
            height: 160px;
          }
          &::-webkit-scrollbar {
            /*滚动条整体样式*/
            width: 0; /*高宽分别对应横竖滚动条的尺寸*/
          }
          &:hover {
            &::-webkit-scrollbar {
              /*滚动条整体样式*/
              width: 3px; /*高宽分别对应横竖滚动条的尺寸*/
            }
            &::-webkit-scrollbar-thumb {
              /*滚动条里面小方块*/
              border-radius: 10px;
              background: rgba(144, 147, 153, 0.5);
            }
            &::-webkit-scrollbar-track {
              /*滚动条里面轨道*/
              border-radius: 10px;
              background: transparent;
            }
          }
        }
      }
    }
  }
  .time-range-picker-dialog-footer {
    padding: 10px;
    border-top: 1px solid #d9d9d9;
    &-btn {
      display: flex;
      align-items: center;
      justify-content: space-between;
      .now,
      .confirm {
        font-weight: 800;
        color: #409eff;
      }
      .cancel {
        color: #303133;
        margin-right: 20px;
      }
      .now,
      .confirm,
      .cancel {
        cursor: pointer;
      }
      .hidden {
        visibility: hidden;
      }
    }
  }
}
</style>